#include "Chr0Import.h"
#include "ToyMgr.h"
#include "ChrzFile.h"

void    LoadKeyFrameToAnimation(CTaAnim*,CTaObject*,ChrzNode*);
void    LoadKeyDataToAniItem(CTaAnimItem*,ChrzKeyFrameData*,UINT,bool);

TA_PLUGIN_EXPORT void TaGetSdkVersion(DWORD* pVersionMS, DWORD* pVersionLS)
{
	if(pVersionMS)
		*pVersionMS = TA_SDK_VERSION_MS;
	if(pVersionLS)
		*pVersionLS = TA_SDK_VERSION_LS;
}

TA_PLUGIN_EXPORT LPCTSTR 	TaGetProductName ()
{
    return  "Chr0AniPlugin";
}


TA_PLUGIN_EXPORT LPCTSTR 	TaGetProductVersion ()
{
    return  "0.0.1";
}


TA_PLUGIN_EXPORT LPCTSTR 	TaGetManufacturerName ()
{
    return  "SRX-R2";
}


TA_PLUGIN_EXPORT UINT 	TaGetPluginElements ()
{
	UINT nRet = 0;
#ifdef USE_IMPORT_FUNC
	nRet |= TA_PLUGIN_ELEMENT_IMPORT;
#endif
#ifdef USE_EXPORT_FUNC
	nRet |= TA_PLUGIN_ELEMENT_EXPORT;
#endif
	return nRet;
}

TA_PLUGIN_EXPORT BOOL 	TaInitPlugin (HMODULE hModule)
{
	if(!TaInitLib(hModule))
		return FALSE;

    return TRUE;
}


TA_PLUGIN_EXPORT UINT 	TaGetImportFileTypeCount ()
{
    return 1;
}

TA_PLUGIN_EXPORT LPCTSTR 	TaGetImportFileType (UINT nIndex)
{
    return  "chr0 animation(*.chr0)";
}

TA_PLUGIN_EXPORT LPCTSTR 	TaGetImportFileExt (UINT nIndex)
{
    return  ".chr0";
}


TA_PLUGIN_EXPORT BOOL 	TaImportFile (UINT nIndex, LPCTSTR pszFilePath, CTaScene *pScene, CTaObject *pRootModel)
{
    using namespace std;

    ChrzFile        *chrz;
    ChrzNode        *chrznode;
    string         filename(pszFilePath);
    int             aitemcount,framecount,keycount;
    CTaObject       *bone;
    CToyMgr         tmgr(pScene);
    CTaAnim         *nani;
    CTaAnimItem     *anitem;
    if( !readchrzfromfile(pszFilePath,&chrz) || chrz->nodecount==0 || chrz->framecount==0 )
        return FALSE;

    aitemcount = chrz->nodecount;

    int fnstart = filename.rfind("\\");
    int fnend   = filename.rfind(".");


    nani = TaCreateAnim();
    nani->SetFirstFrame(1);
    nani->SetLastFrame(chrz->framecount);
    nani->SetFps(30);
    nani->SetName(filename.substr(fnstart+1,fnend-fnstart-1).c_str());
//*
    for(int i=0;i<aitemcount;i++)
    {
        chrznode = chrz->aninodes[i];
        bone = tmgr.GetBoneByName(chrznode->bname);
        if(!bone )
            continue;
//        if(!strcmp(chrznode->bname,"COG"))
//            continue;
        LoadKeyFrameToAnimation(nani,bone,chrznode);

    } // */

    tmgr.GetRoot()->AddModelAnim(nani);
    tmgr.GetRoot()->SetModelCurAnim(nani);
    nani->SetCurFrame(1.0);

    freechrz(chrz);
    return TRUE;
}


void    LoadKeyFrameToAnimation(CTaAnim *ani,CTaObject *tob,ChrzNode *chrzn)
{
    CTaAnimItem     *anitem;

    if(chrzn->scalekeys)
    {
        if(chrzn->scalekeys->xkeycount!=0)
        {
            anitem = ani->CreateObjectItem(TA_ANIM_ITEM_SCALE_X,tob);
            LoadKeyDataToAniItem(anitem,chrzn->scalekeys->xkeys,chrzn->scalekeys->xkeycount,chrzn->scalekeys->islinear);
        }

        if(chrzn->scalekeys->ykeycount!=0)
        {
            anitem = ani->CreateObjectItem(TA_ANIM_ITEM_SCALE_Y,tob);
            LoadKeyDataToAniItem(anitem,chrzn->scalekeys->ykeys,chrzn->scalekeys->ykeycount,chrzn->scalekeys->islinear);
        }
        if(chrzn->scalekeys->zkeycount!=0)
        {
            anitem = ani->CreateObjectItem(TA_ANIM_ITEM_SCALE_Z,tob);
            LoadKeyDataToAniItem(anitem,chrzn->scalekeys->zkeys,chrzn->scalekeys->zkeycount,chrzn->scalekeys->islinear);
        }
    }

    if(chrzn->rotkeys)
    {
         if(chrzn->rotkeys->xkeycount!=0)
        {
            anitem = ani->CreateObjectItem(TA_ANIM_ITEM_ROTATE_X,tob);
            LoadKeyDataToAniItem(anitem,chrzn->rotkeys->xkeys,chrzn->rotkeys->xkeycount,chrzn->rotkeys->islinear);
        }

        if(chrzn->rotkeys->ykeycount!=0)
        {
            anitem = ani->CreateObjectItem(TA_ANIM_ITEM_ROTATE_Y,tob);
            LoadKeyDataToAniItem(anitem,chrzn->rotkeys->ykeys,chrzn->rotkeys->ykeycount,chrzn->rotkeys->islinear);
        }
        if(chrzn->rotkeys->zkeycount!=0)
        {
            anitem = ani->CreateObjectItem(TA_ANIM_ITEM_ROTATE_Z,tob);
            LoadKeyDataToAniItem(anitem,chrzn->rotkeys->zkeys,chrzn->rotkeys->zkeycount,chrzn->rotkeys->islinear);

        }
    }

    if(chrzn->transkeys)
    {
         if(chrzn->transkeys->xkeycount!=0)
        {
            anitem = ani->CreateObjectItem(TA_ANIM_ITEM_TRANSLATE_X,tob);
            LoadKeyDataToAniItem(anitem,chrzn->transkeys->xkeys,chrzn->transkeys->xkeycount,chrzn->transkeys->islinear);
            anitem->UpdateSpline();
        }

        if(chrzn->transkeys->ykeycount!=0)
        {
            anitem = ani->CreateObjectItem(TA_ANIM_ITEM_TRANSLATE_Y,tob);
            LoadKeyDataToAniItem(anitem,chrzn->transkeys->ykeys,chrzn->transkeys->ykeycount,chrzn->transkeys->islinear);
            anitem->UpdateSpline();
        }
        if(chrzn->transkeys->zkeycount!=0)
        {
            anitem = ani->CreateObjectItem(TA_ANIM_ITEM_TRANSLATE_Z,tob);
            LoadKeyDataToAniItem(anitem,chrzn->transkeys->zkeys,chrzn->transkeys->zkeycount,chrzn->transkeys->islinear);
            anitem->UpdateSpline();
        }
    }

        //anitem = ani->CreateObjectItem(TA_ANIM_ITEM_ROTATE_X,tob);
}

void    LoadKeyDataToAniItem(CTaAnimItem *anitem,ChrzKeyFrameData *kfd,UINT keycount,bool islinear)
{
    if(!anitem || !kfd || keycount==0)
        return;

    TA_TAN_TYPE   tantype = (islinear ? TA_TAN_LINEAR : TA_TAN_SPLINE);

    if(tantype = TA_TAN_LINEAR)
    {
        for(UINT i=0;i<keycount;i++,kfd++)
        {
            anitem->InsertKeyFrame( (float)kfd->frameid,kfd->value,
                                    &tantype,&tantype); //,
                                    //&(kfd->tan), &(kfd->tan) );
        }
    }
    else
    {
         for(UINT i=0;i<keycount;i++,kfd++)
        {
            anitem->InsertKeyFrame( (float)kfd->frameid,kfd->value,
                                    &tantype,&tantype);
                                    //&(kfd->tan), &(kfd->tan) );
        }

    }
    anitem->UpdateSpline();
    return;
}
